package com.bbs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bbs.entity.*;
import com.bbs.mapper.IBBSPostCommentMapper;
import com.bbs.mapper.IBBSPostMapper;
import com.bbs.mapper.IBBSUserMapper;
import com.bbs.service.IBBSPostCommentService;
import com.bbs.util.BeanUtil;
import com.bbs.util.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @PackageName: com.bbs.service.impl
 * @ClassName: BBSPostCommentImpl
 * @Description:
 * @Author: Rambo
 * @Data: 2024/6/18 11:03
 */
@Service
public class BBSPostCommentServiceImpl implements IBBSPostCommentService {
    @Autowired
    private IBBSPostMapper bbsPostMapper;
    @Autowired
    private IBBSPostCommentMapper bbsPostCommentMapper;
    @Autowired
    private IBBSUserMapper bbsUserMapper;

    /**
     * 添加评论
     * @param postComment
     * @return
     */
    @Override
    @Transactional
    public Boolean addPostComment(BBSPostComment postComment) {
        // 查询评论的帖子是否存在
        BBSPost bbsPost = bbsPostMapper.selectOne(
                new LambdaQueryWrapper<BBSPost>()
                        .eq(BBSPost::getPostId, postComment.getPostId())
        );
        if (bbsPost == null) {
            return false;
        }

        // 查询评论用户的状态
        BBSUser bbsCommentUser = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, postComment.getCommentUserId())
        );
        if (bbsCommentUser.getUserStatus() == 1 || bbsCommentUser == null) {
            return false;
        }

        // 修改帖子的评论数
        int update = bbsPostMapper.update(
                null,
                new LambdaUpdateWrapper<BBSPost>()
                        .eq(BBSPost::getPostId, postComment.getPostId())
                        .set(BBSPost::getPostComments, bbsPost.getPostComments() + 1)
        );

        int insert = bbsPostCommentMapper.insert(postComment);

        return update > 0 && insert > 0;
    }

    /**
     * 删除评论
     * @param commentId 评论id
     * @param userId 用户id
     * @return
     */
    @Override
    @Transactional
    public Boolean delPostComment(Long commentId, Long userId) {
        // 通过评论id查询该评论是否存在
        BBSPostComment bbsPostComment = bbsPostCommentMapper.selectOne(
                new LambdaQueryWrapper<BBSPostComment>()
                        .eq(BBSPostComment::getCommentId, commentId)
        );
        // 若帖子不存在则不能删除
        if (bbsPostComment == null) {
            return false;
        }

        // 通过userId查询用户信息
        BBSUser bbsUser = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, userId)
        );
        // 若查询到的用户不存在或用户被禁用则不能删除
        if (bbsUser == null || bbsUser.getUserStatus() == 1) {
            return false;
        }

        // 若评论存在则查询该评论的帖子信息
        BBSPost bbsPost = bbsPostMapper.selectOne(
                new LambdaQueryWrapper<BBSPost>()
                        .eq(BBSPost::getPostId, bbsPostComment.getPostId())
        );
        // 若评论的帖子不存在则不能删除
        if (bbsPost == null) {
            return false;
        }

        long postCommentsCount = bbsPost.getPostComments() - 1;
        if (postCommentsCount >= 0) {
            bbsPost.setPostComments(postCommentsCount);
        }

        // 判断评论所关联的用户，及评论的帖子的关联用户，即评论发布者和贴子发布者均有权利删除该条评论
        if (userId.equals(bbsPostComment.getCommentUserId()) || userId.equals(bbsPost.getPublishUserId())) {
            // 删除评论
            int delete = bbsPostCommentMapper.delete(
                    new LambdaQueryWrapper<BBSPostComment>()
                            .eq(BBSPostComment::getCommentId, commentId)
            );

            // 修改该篇帖子的评论数字段
            int update = bbsPostMapper.update(bbsPost,
                    new LambdaUpdateWrapper<BBSPost>()
                            .eq(BBSPost::getPostId, bbsPost.getPostId())
            );
            return delete > 0 && update > 0;
        }

        return false;
    }

    /**
     * 根据帖子id查询评论列表
     * @param postId
     * @param commentPage
     * @return
     */
    @Override
    public PageResult getCommentsByPostId(Long postId, int commentPage) {
        // 查询评论总数
        Long total = bbsPostCommentMapper.selectCount(
                new LambdaQueryWrapper<BBSPostComment>()
                        .eq(BBSPostComment::getIsDeleted, 0)
                        .eq(BBSPostComment::getPostId, postId)
        );

        // 创建分页对象
        Page<BBSPostComment> page = new Page<>(commentPage, 6);
        // 分页查询评论列表
        Page<BBSPostComment> bbsPostCommentPage = bbsPostCommentMapper.selectPage(page,
                new QueryWrapper<BBSPostComment>()
                        .eq("is_deleted", 0)
                        .eq("post_id", postId)
                        .orderByDesc("comment_id")
        );
        List<BBSPostComment> bbsPostCommentList = bbsPostCommentPage.getRecords();

        // 创建BBSPostCommentListEntity列表类
        List<BBSCommentListEntity> bbsCommentListEntities = new ArrayList<>();

        // 数据格式转换
        if (!CollectionUtils.isEmpty(bbsPostCommentList)) {
            // 将评论BBSPostComment列表转换为BBSPostCommentListEntity列表类
            bbsCommentListEntities = BeanUtil.copyList(bbsPostCommentList, BBSCommentListEntity.class);

            /* 遍历BBSPostCommentListEntity列表类，获取每个评论的评论发布者信息
                将 bbsPostCommentListEntities 集合中的每个 BBSPostCommentListEntity 对象的 commentUserId 属性提取出来，转换为一个 List
                    bbsPostCommentListEntities.stream() 创建了一个流（Stream）
                    map(BBSPostCommentListEntity::getCommentUserId) 将每个 BBSPostCommentListEntity 对象的 commentUserId 属性提取出来，转换为一个流
                    collect(Collectors.toList()) 将流中的元素收集成一个新的 List
             */
            List<Long> userIds = bbsCommentListEntities.stream().map(BBSCommentListEntity::getCommentUserId).collect(Collectors.toList());
            // 被回复评论的评论者UserId
            List<Long> parentUserIds = bbsCommentListEntities.stream().map(BBSCommentListEntity::getParentCommentUserId).collect(Collectors.toList());

            // 分别查询评论发布者信息及被回复者信息
            List<BBSUser> bbsUsers = bbsUserMapper.selectList(
                    new LambdaQueryWrapper<BBSUser>()
                            .in(BBSUser::getUserId, userIds)
            );
            List<BBSUser> parentUsers = bbsUserMapper.selectList(
                    new LambdaQueryWrapper<BBSUser>()
                            .in(BBSUser::getUserId, parentUserIds)
            );

            // 封装回复者信息
            if (!CollectionUtils.isEmpty(bbsUsers)) {
                /*
                    将一个 BBSUser 对象的列表转换为一个 Map，其中 userId 作为键，对象本身作为值,为了处理可能存在的键冲突，保留第一个出现的实体
                        bbsUsers.stream() 创建了一个流（Stream）
                        Collectors.toMap(BBSUser::getUserId, Function.identity(), (entity1, entity2) -> entity1)
                            Function.identity() 返回一个函数，该函数返回输入参数本身
                            (entity1, entity2) -> entity1 表示当两个键值对具有相同的键时，处理冲突,保留第一个实体
                 */
                Map<Long, BBSUser> bbsUserMap = bbsUsers.stream().collect(Collectors.toMap(BBSUser::getUserId, Function.identity(), (entity1, entity2) -> entity1));

                // 遍历BBSPostCommentListEntity列表类，将评论发布者信息封装到BBSPostCommentListEntity对象中
                for (BBSCommentListEntity bbsPostCommentListEntity : bbsCommentListEntities) {
                    if (bbsUserMap.containsKey(bbsPostCommentListEntity.getCommentUserId())) {
                        //设置头像字段和昵称字段
                        BBSUser tempUser = bbsUserMap.get(bbsPostCommentListEntity.getCommentUserId());
                        bbsPostCommentListEntity.setHeadImgUrl(tempUser.getHeadImgUrl());
                        bbsPostCommentListEntity.setNickName(tempUser.getNickName());
                    }
                }
            }

            // 添加被回复者的信息
            if (!CollectionUtils.isEmpty(parentUsers)) {
                //添加被回复者的信息
                Map<Long, BBSUser> parentUserMap = parentUsers.stream().collect(Collectors.toMap(BBSUser::getUserId, Function.identity(), (entity1, entity2) -> entity1));
                for (BBSCommentListEntity bbsCommentListEntity : bbsCommentListEntities) {
                    if (parentUserMap.containsKey(bbsCommentListEntity.getParentCommentUserId())) {
                        //在评论内容前加上"@xxx "
                        BBSUser tempUser = parentUserMap.get(bbsCommentListEntity.getParentCommentUserId());
                        bbsCommentListEntity.setCommentBody("@" + tempUser.getNickName() + "：" + bbsCommentListEntity.getCommentBody());
                    }
                }
            }
        }
        PageResult pageResult = new PageResult(bbsCommentListEntities, total.intValue(), 6, commentPage);
        return pageResult;
    }

    /**
     * 获取用户最近评论列表
     * @param userId
     * @return
     */
    @Override
    public List<RecentCommentListEntity> getRecentCommentListByUserId(Long userId) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 获取七天前的时间
        LocalDateTime sevenDaysAgo = now.minusDays(7);
        // 获取用户最近评论列表
        List<BBSPostComment> recentCommentList = bbsPostCommentMapper.selectList(
                new LambdaQueryWrapper<BBSPostComment>()
                        .eq(BBSPostComment::getCommentUserId, userId)
                        .eq(BBSPostComment::getIsDeleted, 0)
                        .between(BBSPostComment::getCommentCreateTime, sevenDaysAgo, now)
                        .last("limit 6")
        );

        // 创建一个RecentCommentListEntity列表类
        List<RecentCommentListEntity> recentCommentListEntities = new ArrayList<>();
        // 数据格式转换
        if (!CollectionUtils.isEmpty(recentCommentList)) {
            recentCommentListEntities = BeanUtil.copyList(recentCommentList, RecentCommentListEntity.class);

            // 帖子id
            List<Long> postIds = recentCommentList.stream().map(BBSPostComment::getPostId).collect(Collectors.toList());

            // 查询帖子信息
            List<BBSPost> bbsPosts = bbsPostMapper.selectList(
                    new LambdaQueryWrapper<BBSPost>()
                            .in(BBSPost::getPostId, postIds)
            );

            if (!CollectionUtils.isEmpty(bbsPosts)) {
                // 封装帖子数据
                Map<Long, BBSPost> bbsPostMap = bbsPosts.stream().collect(Collectors.toMap(BBSPost::getPostId, Function.identity(), (entity1, entity2) -> entity1));
                for (RecentCommentListEntity recentCommentListEntity : recentCommentListEntities) {
                    if (bbsPostMap.containsKey(recentCommentListEntity.getPostId())) {
                        //设置帖子标题
                        BBSPost bbsPost = bbsPostMap.get(recentCommentListEntity.getPostId());
                        recentCommentListEntity.setPostTitle(bbsPost.getPostTitle());
                    }
                }
            }
        }
        return recentCommentListEntities;
    }
}
